<?php
/**
 * Created by PhpStorm
 * User: ZhouFurong
 * Date: 2020/12/8
 * Time: 17:10
 */

class customer
{
    private static $instance;

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            static::$instance = new static();
        }
        return static::$instance;
    }

    public static function get($abstract, $vars = [], $newInstance = false)
    {
        return static::getInstance()->make($abstract, $vars, $newInstance);
    }

    public function make($abstract, $vars = [], $newInstance = false)
    {
        if (true === $vars) {
            // 如果变量不为空，则总是创建新的实例化对象
            $newInstance = true;
            $vars = [];
        }

        // 该类名是否已经被设置
        $abstract = isset($this->name[$abstract]) ? $this->name[$abstract] : $abstract;

        // 如果该实例已经在容器中了，并且不是一个新的实例的话，直接返回容器已经绑定的实例
        if (isset($this->instances[$abstract]) && !$newInstance) {
            return $this->instances[$abstract];
        }

        // 该类名，是否已经绑定到容器中
        if (isset($this->bind[$abstract])) {
            $concrete = $this->bind[$abstract];// 获取具体的类名

            // 是否为一个匿名函数
            if ($concrete instanceof Closure) {
                $object = $this->invokeFunction($concrete, $vars);
            } else {
                $this->name[$abstract] = $concrete;
                return $this->make($concrete, $vars, $newInstance);
            }
        } else {
            // 不在容器中的类，直接调用 invokeClass() 方法直接实例化，该方法使用了反射类 ReflectionClass
            $object = $this->invokeClass($abstract, $vars);
        }

        // 如果不是一个新的实例，则添加到实例数组中去
        if (!$newInstance) {
            $this->instances[$abstract] = $object;
        }

        // 返回实例化后的对象
        return $object;
    }

}




var_dump(get_class(customer::getInstance()));
echo '-----------------------', PHP_EOL;
var_dump(get_class(customer::getInstance()));